<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    
</body>
<script>
    //1. 是否允许重复申明？ var允许的   let不允许的 
    var a1 = 10;
    var a1 = 20;
    console.log('a1 = ' + a1) 

    let a2 = 10;
    // let a2 = 20;  //Identifier 'a2' has already been declared 
    console.log('a2 = ' + a2) 
</script>

<script>
    //2. 是否存在预解析  var存在预解析   let不存在预解析 
    console.log('b1 = ' + b1) //undefined 
    var b1 = '111';

    // console.log('b2 = ' +b2)  //Cannot access 'b2' before initialization 
    // let b2 = '222'; 

    s1();  //s1 is not a function 
    var s1 = function(){
        return 'aaa';
    }

    // s2();   //Cannot access 's2' before initialization 
    let s2 = function(){
        return 'bbb';
    }
</script>
<script>
    // 是否存在提升变量？ var可以提升变量  let不允许提升变量 
    var c1 = 10;
    {
        var c1 = 20;
    }
    console.log("c1 = "+c1) //20 

    let c2 = 10;
    {
        let c2 = 20;
    }
    console.log("c2 = "+c2) //10 
</script>
<script>
    /*
    因为 var 声明的 i 是函数 / 
    全局作用域变量，循环过程中，i 的值会持续变化（0→1→2→3→4→5 ，当 i=5 时循环退出 ）。
    setTimeout 里的函数 “暂缓” 执行，等 1 秒后执行时，循环早已结束，i 已经变成 5 ，
    所以 5 个定时器函数执行时，拿到的 i 都是 5 ，就会输出 5 次 5 。
    */
    for(var i=0;i<5;i++){
        // 延时器 
        setTimeout(function(){
            console.log(i) //5 5 5 5 5 
        }, 1000)
    }
    console.log('i = ' +i) //i = 5 

     /*
    let 声明的变量是块级作用域，每次循环会创建一个独立的 i ，定时器函数能拿到对应循环轮次的 i 值，因此输出 0 到 4 。
    */
    for(let j=0;j<5;j++){
        // 延时器 
        setTimeout(function(){
            console.log(j) //0 1 2 3 4 
        }, 1000)
    }
    // console.log('j = ' +j) //报错（let 块级作用域，外部无法访问 ）
</script>
<script>
    //1.const声明变量时值时不可变的
    const a=10;
    a=100;//这样就会报错
    console.log(a);
    //2.常量必须赋初始值
    // const b;这样在编译期就不通过
</script>
</html>